home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 2: Applications
/
Linux Cubed Series 2 - Applications.iso
/
math
/
gle-3.000
/
gle-3
/
gle
/
run.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-07
|
27KB
|
1,171 lines
#include "all.h"
#include <math.h>
#include "mygraph.h" /* Prototypes for all the graph routines */
int text_def(char *ss);
int g_psarrow(double x1, double y1, double x2, double y2, int flag);
int g_arrowline(double dx, double dy, int flag);
int g_arrowpoints(double cx,double cy,double dx,double dy, double *ax1,double *ay1
,double *ax2,double *ay2, double *nx, double *ny);
int name_join(char *a, char *b, int j);
int box_start(void);
int box_end(void);
int g_arrow(double dx, double dy);
int run_bigfile(char *ss);
#define MAXBOX 10
extern int this_line;
extern int trace_on;
static char *box_name[MAXBOX];
static double box_y1[MAXBOX], box_x1[MAXBOX], box_y2[MAXBOX], box_x2[MAXBOX];
static int box_nobox[MAXBOX];
static int32 box_fill[MAXBOX];
static double box_add[MAXBOX];
static int path_clip[4],path_stroke[4];
static int32 path_fill[4];
static double path_x[4],path_y[4];
static int npath,nbox;
int done_open;
#define true (!false)
#define false 0
/*---------------------------------------------------------------------------*/
/* gle FILE io stuff. (fopen fclose fread fwrite) */
#define F_MAXCHAN 5
static int f_end[F_MAXCHAN];
static char *f_buff[F_MAXCHAN];
static FILE *f_chan[F_MAXCHAN];
static int f_read[F_MAXCHAN];
static char *f_nexttok[F_MAXCHAN];
int f_getchan(void);
void f_readahead(int chn);
int f_testchan(int chn);
void siffree(char **s);
void f_getline(int chn);
char *f_gettok(int chn);
static int chn;
int f_eof(int chn);
char *f_getnext(int chn);
/*---------------------------------------------------------------------------*/
/* pos= Offset to find the data */
/* idx= For switches, which can only have one value. */
/* The pos is the order the items will be placed in the pcode */
/*
/* Switches int32 placed in directly, 1 present, 0 not present
/* expressions LONG* pointed to, 0 if not present.
/* color/fill LONG* Pointer to exp 0 if not present.
/* marker LONG* Pointer to exp 0 if not present.
/* lstyle LONG* Pointer to exp 0 if not present.
/* font int32* Pointer to string expression.
*/
extern char *mainkey[];
extern int gle_debug;
int can_fillpath;
int init_run_done;
#define readval(x) eval(pcode,&cp,&x,ostr,&otyp)
#define readxy(x,y) {eval(pcode,&cp,&x,ostr,&otyp);eval(pcode,&cp,&y,ostr,&otyp);}
#define readstr(s) eval(pcode,&cp,&x,s,&otyp)
#define readlong(i) i = *(pcode+cp++)
#define readvalp(x,p) {zzcp=0; eval(p,&zzcp,&x,ostr,&otyp);}
#define dbg if ((gle_debug & 16)>0)
static int for_level,for_skip,for_loop,if_findelse,if_findendif,if_level;
void for_init(void)
{
for_loop = 0;
for_level = 0;
for_skip = 0;
if_findelse = 0;
if_findendif = 0;
if_level = 0;
}
/*---------------------------------------------------------------------------*/
/* Input is pcode, output is text equiv.*/
do_pcode(int *srclin, int32 *pcode, int plen, int *pend)
/* srclin = The source line number */
/* pcode = a pointer to the pcode output buffer */
/* plne = a pointer to the length of the pcode output */
{
double oval;
union {double d; int32 l; int32 ll[2];} both;
int otyp,cp=0,i,zzcp;
static double loopstep[30];
static int loopadr[30],nloop;
double lll,rrr,uuu,ddd;
char ostr[255];
char *pss;
char *zzz;
int p;
union ppboth {int32 l; short s[2];} bth;
double x,y,sx,sy,ox,oy,x1,y1,x2,y2,x3,y3,a1,a2,r,z;
int t,j,jj,ptr,ptr_fill,mask_just,mask_nostroke,marrow;
static char ss[255],ss2[80];
if (!init_run_done) {
init_run_done = true;
g_get_type(ss);
if (strstr(ss,"FILLPATH")!=NULL) can_fillpath = true;
}
this_line = *srclin;
/* dbg gprint("Gle debug %d \n ",gle_debug);
dbg gprint("PP> ");
dbg for (i=0; i<plen; i++) {
bth.l = *(pcode+i);
dbg gprint("%ld ",bth.l);
}
dbg gprint("\n");
*/
dbg {
gprint("HEX> ");
for (i=0; i<plen; i++) {
bth.l = *(pcode+i);
gprint("%lx ",bth.l);
if (i==14) gprint("\n");
}
gprint("\n");
}
if (plen==0) return;
if (*(pcode)==0) return;
p = *(pcode+((cp)++));
cmd_name(p,&pss);
dbg gprint("Command %d {%s} \n",p,pss);
sprintf(ss,"Command %d {%s} \n",p,pss);
g_source(ss);
if (if_findelse) {
dbg gprint("SKIP in skip findelse \n");
switch (p) {
case 13 : /* else */
if (if_level==0) {
if_findelse = false;
}
break;
case 14 : /* end xxx */
readlong(jj);
if (jj==6) { /* end if */
if (if_level==0) {
if_findelse = false;
} else if_level--;
}
break;
case 22 : /* if */
if_level++;
break;
}
return;
}
if (if_findendif) {
dbg gprint("SKIP, findendif \n");
switch (p) {
case 14 : /* end xxx */
readlong(jj);
if (jj==6) { /* end if */
if (if_level==0) {
if_findendif = false;
} else if_level--;
} else gprint("Wrong end %d \n",jj);
break;
case 22 : /* if */
if_level++;
break;
}
return;
}
if (for_skip ) {
switch (p) {
case 47: /* until */
case 18 : /* for */
for_level++;
break;
case 30 : /* next */
if (for_level==0) {
for_skip = false;
} else for_level--;
break;
}
return;
}
if (!done_open) {
if (p!=42 && p!=53 && p!=0) {
gprint("No SIZE command at top of graph, assuming 10cm by 10cm\n");
g_open(10.0,10.0);
done_open = true;
return;
}
}
switch (p) {
case 53: /* comment */
case 0: /* blank line */
break;
case 1: /* ALINE x y ARROW both | start | end */
readval(x);
readval(y);
dbg gprint("x=%f, y=%f \n",x,y);
marrow = *(pcode + (cp++));
dbg gprint("arrow mask %d \n",marrow);
g_arrowline(x,y,marrow);
break;
case 2: /* AMOVE */
readval(x);
readval(y);
g_move(x,y);
break;
case 3: /* ARC */
readval(r);
readxy(a1,a2);
g_get_xy(&ox,&oy);
ptr = *(pcode + cp); /* cx,cy */
if (ptr) {
readvalp(x,pcode + cp + ptr);
ox+=x;
}
ptr = *(pcode + cp + 1); /* cx,cy */
if (ptr) {
readvalp(y,pcode + cp + ptr);
oy+=y;
}
g_arc(r,a1,a2,ox,oy);
break;
case 4: /* ARCTO */
readxy(x1,y1);
readxy(x2,y2);
readval(r);
g_get_xy(&ox,&oy);
g_arcto(x1+ox,y1+oy,x2+ox+x1,y2+oy+y1,r);
break;
case 51: /* Assignment var=exp */
readlong(jj);
readval(x);
if (otyp==1) var_set(jj,x);
if (otyp==2) var_setstr(jj,ostr);
break;
case 5: /* BEGIN box | path | scale | rotate | EXTERNAL */
g_flush();
i = *(pcode + cp++);
dbg gprint(" begin %d \n",i);
switch (i) {
case 1: /* PATH stroke fill clip */
npath++;
g_get_xy(&path_x[npath],&path_y[npath]);
path_stroke[npath] = *(pcode + cp);
ptr = *(pcode + ++cp);
path_fill[npath] = 0;
if (ptr) {
readvalp(z,pcode+cp+ptr);
memcpy(&path_fill[npath],&z,4);
}
path_clip[npath] = *(pcode + ++cp);
g_set_path(true);
g_newpath();
break;
case 2: /* BOX add,fill,nobox,name */
box_start();
ptr = *(pcode + cp);
if (ptr) readvalp(box_add[nbox],pcode+cp+ptr);
ptr = *(pcode + ++cp);
if (ptr) {
readvalp(z,pcode+cp+ptr);
memcpy(&box_fill[nbox],&z,4);
}
box_nobox[nbox] = *(pcode + ++cp);
ptr = *(pcode + ++cp);
if (ptr) {
readvalp(z,pcode+cp+ptr);
box_name[nbox] = sdup(ostr);
}
break;
case 3: /* SCALE */
readxy(x,y);
g_gsave();
g_scale(x,y);
break;
case 21: /* shear */
readxy(x,y);
g_gsave();
g_shear(x,y);
break;
case 4: /* ROTATE */
readval(x);
g_gsave();
g_rotate(x);
break;
case 5: /* TRANSLATE */
readval(x); readval(y);
g_gsave();
g_translate(x,y);
g_rmove(0.0,0.0);
break;
case 6: /* if */
case 7: /* sub */
gprint("odd begin %d\n",i);
break;
case 8: /* name */
box_start();
box_nobox[nbox] = true;
readval(z);
box_name[nbox] = sdup(ostr);
break;
case 9: /* text */
ptr = *(pcode + cp);
z = 0;
if (ptr) readvalp(z,pcode+cp+ptr);
begin_text(srclin,pcode,&cp,z);
break;
case 18: /* tab (tabbing, table) */
begin_tab(srclin,pcode,&cp);
break;
case 10: /* graph */
begin_graph(srclin,pcode,&cp);
break;
case 11: /* xaxis */
case 12: /* yaxis */
case 13: /* x2axis */
case 14: /* y2axis */
break;
case 16: /* KEY */
begin_key(srclin,pcode,&cp);
break;
case 19: /* begin clip */
g_beginclip();
break;
case 17: /* ORIGIN */
g_gsave();
g_get_xy(&x,&y);
g_translate(x,y);
g_move(0.0,0.0);
break;
default: /* error */
gprint("Error, illegal begin option %d \n",i);
break;
}
break;
case 6: /* BEZIER */
readxy(x1,y1);
readxy(x2,y2);
readxy(x3,y3);
g_bezier(x1,y1,x2,y2,x3,y3);
break;
case 7: /* BOX x y left|center|right FILL fexp NAME string */
readval(x);
readval(y);
g_get_xy(&ox,&oy);
x += ox;
y += oy;
dbg gprint("x=%f, y=%f \n",x,y);
mask_just = *(pcode + cp++);
g_dojust(&ox,&oy,&x,&y,mask_just);
mask_nostroke = *(pcode + cp);
ptr_fill = *(pcode + ++cp);
if (ptr_fill) {
readvalp(z,pcode + cp + ptr_fill);
memcpy(&both.d,&z,sizeof(z));
g_set_fill(both.l);
g_box_fill(ox,oy,x,y);
}
if (!mask_nostroke)
g_box_stroke(ox,oy,x,y);
ptr = *(pcode + ++cp); /* name */
if (ptr) {
readvalp(z,pcode + cp + ptr);
name_set(ostr,ox,oy,x,y);
}
dbg gprint("justify mask %d ",mask_just);
dbg gprint("nostroke mask %d ",mask_nostroke);
dbg gprint("fill pointer %d \n",ptr_fill);
break;
case 52: /* CALL or @ (nope, do this inside ASSIGN */
readval(r);
break;
case 8: /* CIRCLE */
readval(r);
g_get_xy(&ox,&oy);
sx = ox; sy = oy;
mask_just = *(pcode + cp++);
x = ox + r;
y = oy + r;
g_dojust(&ox,&oy,&x,&y,mask_just);
g_move(ox,oy);
mask_nostroke = *(pcode + cp++);
ptr_fill = *(pcode + cp);
if (ptr_fill) {
readvalp(z,pcode + cp + ptr_fill);
memcpy(&both.l,&z,4);
g_set_fill(both.l);
g_circle_fill(r);
}
if (!mask_nostroke)
g_circle_stroke(r);
g_move(sx,sy);
break;
case 9: /* CLOSEPATH */
g_closepath();
break;
case 10: /* CURVE x y x y ... change to BEGIN CURVE ... END CURVE */
g_curve(pcode+cp);
break;
case 11: /* DEFINE MARKER name subname */
break;
case 12: /* DFONT */
readstr(ss);
g_dfont(ss);
break;
case 13: /* ELSE */
if_findendif = true;
break;
case 14: /* END */
readlong(jj);
switch (jj) {
case 1: /* end path (stroke,fill,clip) */
if (path_fill[npath]!=0) {
g_set_fill(path_fill[npath]);
g_fill();
}
if (path_stroke[npath]==true) g_stroke();
if (path_clip[npath]==true) g_clip();
if (npath==0) {
gprint("Too many end path's \n");
break;
}
g_move(path_x[npath],path_y[npath]);
npath--;
g_set_path(false);
break;
case 2: /* end box */
box_end();
break;
case 3: /* end scale */
case 21: /* end shear */
case 4: /* end rotate */
case 5: /* end translate */
g_grestore();
break;
case 6: /* end if */
/* do nothing, all done elsewhere I think?? */
break;
case 8: /* end name */
box_end();
break;
case 19: /* clip */
g_endclip();
break;
case 18: /* tab */
case 9: /* text */
break;
case 17: /* end origin */
g_grestore();
break;
default :
gprint("Not a valid end %d \n",jj);
}
break;
case 15: /* FCLOSE */
readval(x);
chn = x;
chn = f_testchan(chn);
if (f_chan[chn]!=NULL) fclose(f_chan[chn]);
f_chan[chn] = NULL;
siffree(&f_buff[chn]);
siffree(&f_nexttok[chn]);
f_buff[chn] = NULL;
break;
case 16: /* FILL */
g_fill();
break;
case 61 : /* fread CHAN a$ x */
case 62 : /* freadln */
readlong(t);
if (t!=49) gprint("FREAD, PCODE ERROR, %d cp %d plen %d\n",t,cp,plen);
readlong(i);
readlong(t);
var_get(i,&x);
chn = x;
chn = f_testchan(chn);
if (p==61 && cp>=plen) gprint("FREAD requires at least two parameters\n");
while (cp<plen) {
readlong(t);
if (t!=49) gprint("FREAD2, PCODE ERROR, %d cp %d plen %d\n",t,cp,plen);
readlong(i); /* variable number */
readlong(t); /* type of variable */
if (t==1) {
x = atof(f_gettok(chn));
var_set(i,x);
} else {
var_setstr(i,f_gettok(chn));
}
}
if (p==62) f_getline(chn);
break;
case 63 : /* fwrite */
case 64 : /* fwriteln */
strcpy(ss2,"");
readlong(t);
readlong(t);
readval(x);
chn = x;
chn = f_testchan(chn);
if (f_read[chn]==0) gprint("You cannot WRITE from a file open for READ {#%d %d} \n",chn,f_read[chn]);
while (cp<plen) {
readlong(t);
if (t!=49) gprint("WRITE, PCODE ERROR, %d cp %d plen %d\n",t,cp,plen);
readlong(t);
if (t==1) {
readval(x);
sprintf(ss,"%g ",x);
} else readstr(ss);
strcat(ss2,ss);
}
if (p==64) strcat(ss2,"\n");
fprintf(f_chan[chn],"%s",ss2);
break;
case 17: /* FOPEN "a.a" inchan read|write */
readstr(ss);
readlong(i); /* channel variable */
readlong(jj); /* 0 = read, 1 = write */
chn = f_getchan();
f_read[chn] = jj;
var_set(i,chn);
if (f_chan[chn]!=NULL) fclose(f_chan[chn]);
if (jj==0) f_chan[chn] = fopen(ss,"r");
else f_chan[chn] = fopen(ss,"w");
if (f_chan[chn]==NULL) {
gprint("Can't open {%s} \n",ss);
f_end[chn] = true;
break;
}
dbg gprint("Opened {%s} chan %d, access %d vari %d \n",ss,chn,jj,i);
f_end[chn] = false;
if (f_read[chn]==0) f_readahead(chn);
break;
case 18: /* FOR v,exp,exp,op,exp */
if (for_loop) {
readlong(jj);
readval(x);
readval(y);
var_get(jj,&x);
x = x + loopstep[nloop];
var_set(jj,x);
var_get(jj,&x);
dbg gprint("got back %f \n",x);
if ( (x > y && loopstep[nloop]>=0) ||
(y > x && loopstep[nloop]<=0) ) {
for_skip = true;
nloop--;
}
for_loop = false;
break;
}
loopadr[++nloop] = *srclin;
readlong(jj); /* variable */
readval(x);
readval(y);
var_set(jj,x);
loopstep[nloop] = 1;
p = *(pcode + cp);
if (p) {
readvalp(z,pcode + cp + p);
loopstep[nloop] = z;
}
break;
case 19: /* GOTO */
case 20: /* GSAVE */
g_gsave();
break;
case 54: /* GRESTORE */
g_grestore();
break;
case 21: /* ICON */
break;
case 22: /* IF EXP */
readval(x);
dbg gprint("If expression = %f \n",x);
if (x==0) if_findelse = true; /* exp was false */
break;
case 23: /* INCLUDE (done in pass, already included) */
break;
case 24: /* INPUT */
case 25: /* JOIN str1,type,str2 */
{
char ss1[90];
readval(z);
strcpy(ss1,ostr);
readlong(jj);
readval(z);
name_join(ss1,ostr,(int) jj);
}
break;
case 26: /* MARKER */
readval(x);
memcpy(&both.d,&x,sizeof(x));
jj = both.l;
g_get_hei(&z);
y = 1;
if (*(pcode+cp)!=0) readval(y);
y = y * z;
g_marker((int) both.l,y);
break;
case 27: /* MOVE name */
readval(z);
name_get(ostr,&ox,&oy,&x,&y);
x = ox;
y = oy;
g_dojust(&ox,&oy,&x,&y,jj);
g_move(x+(x-ox),y+(y-oy));
break;
case 28: /* NARC */
readval(r);
readxy(a1,a2);
g_get_xy(&ox,&oy);
ptr = *(pcode + cp); /* cx,cy */
if (ptr) {
readvalp(x,pcode + cp + ptr);
ox+=x;
}
ptr = *(pcode + cp + 1); /* cx,cy */
if (ptr) {
readvalp(y,pcode + cp + ptr);
oy+=y;
}
g_narc(r,a1,a2,ox,oy);
break;
case 29: /* NEWPATH */
g_newpath();
break;
case 30: /* NEXT */
if (nloop==0) {
gprint("Next without for\n");
break;
}
*srclin = loopadr[nloop]-1;
dbg gprint("%FOR Setting line back to %d nloop %d \n ",*srclin,nloop);
for_loop = true;
break;
case 31: /* PIE ,, not implemented yet */
break;
case 57: /* plotter fonts */
plotter_fonts();
break;
case 58: /* bigfile "filename" */
readstr(ss);
strlwr(ss); /* bit of a kludge but ... */
run_bigfile(ss);
break;
case 55: /* Postscrip fiename x y */
readstr(ss);
strlwr(ss);
readxy(x1,y1);
g_postscript(ss,x1,y1);
break;
case 32: /* PRINT */
break;
case 33: /* RBEZIER */
readxy(x1,y1);
readxy(x2,y2);
readxy(x3,y3);
g_get_xy(&ox,&oy);
x1 += ox; x2 += ox; x3 += ox;
y1 += oy; y2 += oy; y3 += oy;
g_bezier(x1,y1,x2,y2,x3,y3);
break;
case 34: /* REGION */
break;
case 50: /* RETURN exp */
readval(x);
sub_set_return(x);
break;
case 35: /* REVERSE */
g_reverse();
break;
case 36: /* RLINE */
readval(x);
readval(y);
g_get_xy(&ox,&oy);
marrow = *(pcode + (cp++));
dbg gprint("RLINE getxy %f %f \n",ox,oy);
g_arrowline(x+ox,y+oy,marrow);
break;
case 37: /* RMOVE */
readval(x);
readval(y);
g_get_xy(&ox,&oy);
g_move(x+ox,y+oy);
break;
case 38: /* ROTATE */
readval(x);
g_rotate(x);
break;
case 39: /* SAVE name */
g_get_xy(&x,&y);
readval(z);
name_set(ostr,x,y,x,y);
break;
case 40: /* SCALE */
readxy(x,y);
g_scale(x,y);
break;
case 41: /* SET */
for (i=1;i<plen;i++) {
cp = i+1;
dbg gprint("set sub command %d \n",(*(pcode+i)-500));
switch (*(pcode+i)-500) {
/* FIDDLE CP SO THAT READVAL WORKS *** */
case 1: /* height */
readval(x);
g_set_hei(x);
break;
case 2: /* font */
readval(x);
memcpy(&both.l,&x,4);
g_set_font(both.l);
break;
case 3: /* justify */
readlong(jj);
g_set_just(jj);
break;
case 4: /* color */
readval(x);
memcpy(&both.l,&x,4);
g_set_color(both.l);
break;
case 5: /* dashlen */
readval(x);
g_set_line_styled(x);
break;
case 6: /* dash */
readval(x);
i = x;
sprintf(ss,"%d",i);
g_set_line_style(ss);
break;
case 7: /* lwidth */
readval(x);
g_set_line_width(x);
break;
case 10: /* fontlwidth */
readval(x);
g_set_font_width(x);
break;
case 8: /* join */
readlong(jj);
g_set_line_join(jj);
break;
case 9: /* cap */
readlong(jj);
g_set_line_cap(jj);
break;
default :
gprint("Not a valid set sub command {%d} i=%d \n",*(pcode+i),i);
}
i = cp-1;
}
break;
case 42: /* size x y [box]*/
readxy(x,y);
g_open(x,y);
g_get_xy(&ox,&oy);
done_open = true;
mask_just = *(pcode + cp++);
if (mask_just) { /* then draw box */
g_box_stroke(ox,oy,x,y);
}
break;
case 43: /* STROKE */
g_stroke();
break;
case 44: /* SUB */
readlong(jj);
sub_get_startend(jj,&i,&j);
*srclin = j; /* skip past the subroutine */
break;
case 45: /* TEXT */
strcpy(ss,(char *) (pcode+cp));
/* readstr(ss); */
g_text(ss);
g_get_bounds(&x1,&y1,&x2,&y2);
break;
case 60: /* DEFMARKER */
break;
case 59: /* TEXTDEF */
strcpy(ss,(char *) (pcode+cp));
text_def(ss);
break;
case 46: /* TRANSLATE */
readxy(x,y);
g_translate(x,y);
break;
case 47: /* UNTIL */
readval(x);
if (!for_loop) loopadr[++nloop] = *srclin;
for_loop = true;
if (x) {for_skip = true; for_loop = false; nloop--;}
break;
case 48: /* WHILE */
break;
case 49: /* WRITE */
g_get_xy(&ox,&oy);
strcpy(ss2,"");
while (cp<plen) {
readlong(t);
if (t!=49) gprint("WRITE, PCODE ERROR, %d cp %d plen %d\n",t,cp,plen);
readlong(t);
if (t==1) {
readval(x);
sprintf(ss,"%g ",x);
} else readstr(ss);
strcat(ss2,ss);
}
g_text(ss2);
g_move(ox,oy);
break;
default :
gprint("Not a recognized command \n");
}
*pend = cp;
}
/* should be in core.c */
g_arrowline(double x2, double y2, int flag)
{
double x1,y1;
if ((flag&3)==0) {
g_line(x2,y2);
return;
}
g_get_xy(&x1,&y1);
if (!can_fillpath) {
if (flag & 1) g_arrow(x2-x1,y2-y1);
g_line(x2,y2);
if (flag & 2) g_arrow(x1-x2,y1-y2);
return;
}
g_psarrow(x1,y1,x2,y2,flag);
}
g_psarrow(double x1, double y1, double x2, double y2, int flag)
{
double ax1,ax2,ay1,ay2,dx,dy,nx,ny,nnx,nny,xx2,yy2;
int32 cur_color;
xx2 = x2; yy2 = y2;
dx = x2-x1; dy = y2-y1;
g_arrowpoints(x1,y1,dx,dy,&ax1,&ay1,&ax2,&ay2,&nx,&ny);
g_set_path(true);
g_newpath();
if ((flag & 1)>0) {
g_move(ax2,ay2);
g_line(x1,y1);
g_line(ax1,ay1);
g_closepath();
x1 = nx; y1 = ny;
}
g_arrowpoints(x2,y2,-dx,-dy,&ax1,&ay1,&ax2,&ay2,&nx,&ny);
if ((flag & 2)>0) {
g_move(ax2,ay2);
g_line(x2,y2);
g_line(ax1,ay1);
g_closepath();
xx2 = nx; yy2 = ny;
}
g_get_color(&cur_color);
g_set_fill(cur_color);
g_fill();
g_set_path(false);
g_newpath();
g_move(x1,y1);
g_line(xx2,yy2);
g_move(x2,y2);
}
g_arrowpoints(double cx,double cy,double dx,double dy, double *ax1,
double *ay1,double *ax2,double *ay2, double *nnx, double *nny)
{
double radius,angle,alen,nx,ny,width,arrow_angle;
g_get_line_width(&width);
if (width==0) width = .02;
arrow_angle = 10;
if (width>.1) arrow_angle = 20;
if (width>.3) arrow_angle = 30;
g_get_hei(&alen); alen = alen/2;
if (sin(arrow_angle*3.14159/180)*alen < width/1.5) {
alen = (width/1.5) / sin(arrow_angle*3.141592/180);
}
xy_polar(dx,dy,&radius,&angle);
if (radius<0) alen = -alen;
polar_xy(alen,angle+arrow_angle,&dx,&dy);
*ax2 = cx+dx; *ay2 = cy+dy;
polar_xy(alen,angle-arrow_angle,&dx,&dy);
*ax1 = cx+dx; *ay1 = cy+dy;
polar_xy(alen*cos(arrow_angle*3.141592/180),angle,&nx,&ny);
alen = width/2;
if (radius<0) alen = -alen;
cx += nx; cy += ny;
*nnx = cx; *nny = cy;
}
g_arrow(double dx, double dy)
{
double cx,cy,radius,angle,alen;
g_get_xy(&cx,&cy);
xy_polar(dx,dy,&radius,&angle);
g_get_hei(&alen); alen = alen/2;
if (radius<0) alen = -alen;
polar_xy(alen,angle+10.0,&dx,&dy);
g_line(cx+dx,cy+dy);
g_move(cx,cy);
polar_xy(alen,angle-10.0,&dx,&dy);
g_line(cx+dx,cy+dy);
g_move(cx,cy);
}
box_start(void)
{
g_get_bounds(&box_x1[nbox],&box_y1[nbox],&box_x2[nbox],&box_y2[nbox]);
g_init_bounds();
nbox++;
box_add[nbox] = 0;
box_fill[nbox] = 0;
box_name[nbox] = 0;
}
box_end(void)
{
double x1,y1,x2,y2,ox,oy;
if (nbox==0) {
gprint("Too many end boxes \n");
return;
}
g_get_bounds(&x1,&y1,&x2,&y2);
if (x1>(x2+100)) {gprint("Empty box? %g %g ",x1,x2); return;}
x1 -= box_add[nbox]; y1 -= box_add[nbox];
x2 += box_add[nbox]; y2 += box_add[nbox];
g_get_xy(&ox,&oy);
if (box_fill[nbox]!=0) {
g_set_fill(box_fill[nbox]);
g_box_fill(x1,y1,x2,y2);
}
if (!box_nobox[nbox]) {
g_box_stroke(x1,y1,x2,y2);
}
if (box_name[nbox]!=0) {
name_set(box_name[nbox],x1,y1,x2,y2);
myfree(box_name[nbox]);
}
nbox--;
if (box_x1[nbox] <= box_x2[nbox]) {
g_set_bounds(box_x1[nbox],box_y1[nbox]);
g_set_bounds(box_x2[nbox],box_y2[nbox]);
}
g_move(ox,oy);
}
int nm_adjust(int jj,double *sx, double *sy, double ex, double ey,
double x1, double y1, double x2, double y2);
int nm_point(int jj,double *rx, double *ry, double x1,double y1,double x2,double y2);
int nm_split(char *s, char *n, char *p);
name_join(char *o1,char *o2,int marrow)
{
char n1[40],n2[40],p1[9],p2[9],*ss;
double ox,oy,sx,sy,ex,ey,x,y,x1,y1,x2,y2,x3,y3,x4,y4;
int i,jj1,jj2;
strupr(o1); strupr(o2);
if (strstr(o1,".H")!=0 || strstr(o1,".V")!=0) {
ss = o1; o1 = o2; o2 = ss;
if (marrow==2) marrow = 1;
else if (marrow==1) marrow = 2;
}
nm_split(o1,n1,p1);
nm_split(o2,n2,p2);
x1 = 1e30; x3 = 1e30;
name_get(n1,&x1,&y1,&x2,&y2);
name_get(n2,&x3,&y3,&x4,&y4);
if (x1==1e30 || x3 == 1e30) return;
jj1 = pass_justify(p1);
jj2 = pass_justify(p2);
nm_point(jj1,&sx,&sy,x1,y1,x2,y2);
ex = sx; ey = sy;
nm_point(jj2,&ex,&ey,x3,y3,x4,y4);
nm_adjust(jj1,&sx,&sy,ex,ey,x1,y1,x2,y2);
nm_adjust(jj2,&ex,&ey,sx,sy,x3,y3,x4,y4);
g_get_xy(&ox,&oy);
g_move(sx,sy);
if (marrow==2) marrow = 1;
else if (marrow==1) marrow = 2;
g_arrowline(ex,ey,marrow);
/* g_line(ex,ey);
x = ex-sx;
y = ey-sy;
if (x!=0 || y!=0) {
if (marrow & 1) g_arrow(-x,-y);
g_move(sx,sy);
if (marrow & 2) g_arrow(x,y);
g_move(ox,oy);
}
*/
}
nm_point(int jj,double *rx, double *ry, double x1,double y1,double x2,double y2)
{
int jx,jy;
double w,y,d;
if ((jj == 0x2000)) { /* virtical */
if (y2<*ry) *ry = y2;
if (y1>*ry) *ry = y1;
return;
}
if ((jj == 0x3000)) { /* horizontal centre */
if (x2<*rx) *rx = x2;
if (x1>*rx) *rx = x1;
return;
}
jx = (jj & 0xf0) / 16;
jy = jj & 0x0f;
d = jx * (x2-x1)/2;
*rx = x1 + d;
d = jy * (y2-y1)/2;
*ry = y1 + d;
}
nm_adjust(int jj,double *sx, double *sy, double ex, double ey,
double x1, double y1, double x2, double y2)
{
double r1,r2,xa,da,ca,dr,dx,dy,pi,rz,r;
pi = 3.1415925;
if ((jj & 0xf000)==0x5000) {
r1 = (x2-x1)/2;
r2 = (y2-y1)/2;
xy_polar(*sx - ex,*sy - ey,&dr,&da);
xa = da - 180;
xxxa: if (xa > 180) xa = xa - 180;
if (xa < 0) xa = xa + 180;
if ((xa<0) || (xa> 180)) goto xxxa;
if (r1==0) return;
ca = atan(r2/r1)*180/pi;
if (xa < 90) {
rz = r1/cos(pi*xa/180);
if (xa>ca) rz = r2/sin(pi*xa/180);
} else {
xa = xa - 90;
rz = r2/cos(pi*xa/180);
if (xa>(90-ca)) rz = r1/sin(pi*xa/180);
}
dr = dr - rz ;
polar_xy(dr,da,&dx,&dy);
*sx = ex + dx;
*sy = ey + dy;
}
if ((jj & 0xff00)==0x1000) {
r = (x2-x1)/2;
xy_polar(*sx-ex,*sy-ey,&dr,&da);
dr = dr - r;
polar_xy(dr,da,&dx,&dy);
*sx = ex + dx;
*sy = ey + dy;
}
}
nm_split(char *s, char *n, char *p)
{
char *d;
d = strchr(s,'.');
if (d!=0) {
ncpy(n,s,d-s);
strcpy(p,d+1);
} else {
strcpy(n,s);
strcpy(p,"BO");
}
}
int f_getchan(void)
{
int i;
for (i=0; i<F_MAXCHAN; i++) {
if (f_chan[i]==NULL) {
return i;
}
}
gprint("Fatal error, ran out of file handles, don't open so many\n");
return 0;
}
void f_getline(int chn)
{
char buff[1002];
if (f_chan[chn]==NULL) {return;}
if (f_read[chn]!=0) gprint("You cannot read from a file open for WRITe #%d %d \n",chn,f_read[chn]);
if (fgets(buff,1000,f_chan[chn])==NULL) {
f_end[chn] = true;
}
if (feof(f_chan[chn])) f_end[chn] = true;
if (f_buff[chn]!=NULL) myfree(f_buff[chn]);
f_buff[chn] = sdup(buff);
}
int f_eof(int chn)
{
return f_end[chn];
}
char *f_gettok(int chn)
{
static char thistok[80];
if (f_end[chn]) gprint("Reading past end of file %d\n",chn);
strcpy(thistok,f_nexttok[chn]);
f_readahead(chn);
return thistok;
}
void f_init()
{
int i;
for (i=0;i<F_MAXCHAN; i++) {
if (f_chan[i] != NULL) {fclose(f_chan[i]); f_chan[i] = NULL;}
siffree(&f_buff[i]);
siffree(&f_nexttok[chn]);
}
}
void f_readahead(chn)
{
siffree(&f_nexttok[chn]);
f_nexttok[chn] = sdup(f_getnext(chn));
}
char *f_getnext(int chn)
{
char *s;
int blen;
static char tk[81];
if (f_buff[chn]==NULL) f_getline(chn);
tk[0] = 0;
try_again:
if (f_buff[chn]==NULL) return tk;
blen = strlen(f_buff[chn]);
s = strtok(f_buff[chn]," ,=\t\n\x0a\x0c\x0d");
if (s==NULL) goto next_line;
strcpy(tk,s);
if (strlen(s)==blen) f_buff[0] = 0;
else strcpy(f_buff[chn],s+1+strlen(s));
if (*s == '"' || *s == '!' || *s == ';') goto next_line;
return tk;
next_line:
if (f_eof(chn)) return tk;
f_getline(chn);
goto try_again;
}
void siffree(char **s)
{
if (*s != NULL) myfree(*s);
*s = NULL;
}
int f_testchan(int chn)
{
if (chn<0 || chn>F_MAXCHAN) {
gprint("Error in channel number %d\n",chn);
return 0;
}
return chn;
}